package surface;

import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import shape.Shape;
import shape.Square;
import storage.CanvasMemento;
import storage.CareTakerImpl;
import storage.Memento;

public class CanvasTest {

	@Test
	public void testSetShape() {
		CareTakerImpl careTaker = mock(CareTakerImpl.class);
		CanvasImpl canvas = new CanvasImpl(careTaker);
		canvas.addShape(mock(Square.class));
		
		verify(careTaker, times(1)).add(any(CanvasMemento.class));
	}
	
	
	@Test
	public void testRestoreMemento() {
		CanvasImpl canvas = new CanvasImpl(mock(CareTakerImpl.class));
		Shape square = mock(Square.class);
		List<Shape> shapes = new ArrayList<>();
		shapes.add(square);
		Memento memento = new CanvasMemento(shapes);
		
		canvas.restoreMemento(memento);
		
		assertEquals(square, canvas.getShape(0));
	}
	
	
	@Test
	public void testAttach() {
		CanvasImpl canvas = mock(CanvasImpl.class);
		CanvasObserver observer = mock(CanvasObserver.class);
		
		canvas.attach(observer);
		verify(canvas, times(1)).attach(observer);
	}
	
	
	@Test
	public void testDetach() {
		CanvasImpl canvas = mock(CanvasImpl.class);
		CanvasObserver observer = mock(CanvasObserver.class);
		
		canvas.attach(observer);
		canvas.detach(observer);
		verify(canvas, times(1)).detach(observer);
	}
	
	
	@Test
	public void testNotifyObservers() {
		CanvasImpl canvas = new CanvasImpl(mock(CareTakerImpl.class));
		CanvasObserver observer1 = mock(CanvasObserver.class);
		CanvasObserver observer2 = mock(CanvasObserver.class);
		
		canvas.attach(observer1);
		canvas.attach(observer2);
		
		assertEquals(2, canvas.getObservers().size());
		
		canvas.notifyObservers(false);
		
		verify(observer1, times(1)).update(false);
		verify(observer2, times(1)).update(false);
	}
}
